using System;
using System.Drawing;
using System.Windows.Forms;


namespace Agron.UI.Calendar
{
    /// <summary>
    /// 
    /// </summary>
    public abstract class AbstractRenderer
    {
        private Font hourFont;
        private Font minuteFont;

        /// <summary>
        /// Gets the color of all day events back.
        /// </summary>
        /// <value>The color of all day events back.</value>
        public virtual Color AllDayEventsBackColor
        {
            get
            {
                return InterpolateColors(this.BackColor, Color.Black, 0.5f);
            }
        }

        /// <summary>
        /// Gets the base font.
        /// </summary>
        /// <value>The base font.</value>
        public virtual Font BaseFont
        {
            get
            {
                return Control.DefaultFont;
            }
        }

        /// <summary>
        /// Gets the color of the hour seperator.
        /// </summary>
        /// <value>The color of the hour seperator.</value>
        public virtual Color HourSeperatorColor
        {
            get
            {
                return System.Drawing.Color.FromArgb(234, 208, 152);
            }
        }

        /// <summary>
        /// Gets the color of the half hour seperator.
        /// </summary>
        /// <value>The color of the half hour seperator.</value>
        public virtual Color HalfHourSeperatorColor
        {
            get
            {
                return System.Drawing.Color.FromArgb(243, 228, 177);
            }
        }

        /// <summary>
        /// Gets the color of the hour.
        /// </summary>
        /// <value>The color of the hour.</value>
        public virtual Color HourColor
        {
            get
            {
                return System.Drawing.Color.FromArgb(255, 244, 188);
            }
        }

        /// <summary>
        /// Gets the color of the working hour.
        /// </summary>
        /// <value>The color of the working hour.</value>
        public virtual Color WorkingHourColor
        {
            get
            {
                return System.Drawing.Color.FromArgb(255, 255, 213);
            }
        }

        /// <summary>
        /// Gets the color of the back.
        /// </summary>
        /// <value>The color of the back.</value>
        public virtual Color BackColor
        {
            get
            {
                return SystemColors.Control;
            }
        }

        /// <summary>
        /// Gets the color of the selection.
        /// </summary>
        /// <value>The color of the selection.</value>
        public virtual Color SelectionColor
        {
            get
            {
                return SystemColors.Highlight;
            }
        }

        /// <summary>
        /// Gets the hour font.
        /// </summary>
        /// <value>The hour font.</value>
        public virtual Font HourFont
        {
            get
            {
                if (hourFont == null)
                {
                    hourFont = new Font(BaseFont.FontFamily, 14, FontStyle.Regular);
                }

                return hourFont;
            }
        }

                /// <summary>
        /// Gets the minute font.
        /// </summary>
        /// <value>The minute font.</value>
        public virtual Font MinuteFont
        {
            get
            {
                if (minuteFont == null)
                {
                    minuteFont = new Font(BaseFont.FontFamily, 8, FontStyle.Regular);
                }

                return minuteFont;
            }
        }

        /// <summary>
        /// Draws the hour label.
        /// </summary>
        /// <param name="g">The g.</param>
        /// <param name="rect">The rect.</param>
        /// <param name="hour">The hour.</param>
        public abstract void DrawHourLabel(Graphics g, Rectangle rect, int hour);

        /// <summary>
        /// Draws the day header.
        /// </summary>
        /// <param name="g">The g.</param>
        /// <param name="rect">The rect.</param>
        /// <param name="date">The date.</param>
        public abstract void DrawDayHeader(Graphics g, Rectangle rect, DateTime date);

        /// <summary>
        /// Draws the day background.
        /// </summary>
        /// <param name="g">The g.</param>
        /// <param name="rect">The rect.</param>
        public abstract void DrawDayBackground(Graphics g, Rectangle rect);

        /// <summary>
        /// Draws the hour range.
        /// </summary>
        /// <param name="g">The g.</param>
        /// <param name="rect">The rect.</param>
        /// <param name="drawBorder">if set to <c>true</c> [draw border].</param>
        /// <param name="hilight">if set to <c>true</c> [hilight].</param>
        public virtual void DrawHourRange(Graphics g, Rectangle rect, bool drawBorder, bool hilight)
        {
            if (null == g) throw new ArgumentNullException("g");

            using (SolidBrush brush = new SolidBrush(hilight ? this.SelectionColor : this.WorkingHourColor))
            {
                g.FillRectangle(brush, rect);
            }

            if (drawBorder)
                g.DrawRectangle(SystemPens.WindowFrame, rect);
        }

        /// <summary>
        /// Draws the day gripper.
        /// </summary>
        /// <param name="g">The g.</param>
        /// <param name="rect">The rect.</param>
        /// <param name="gripWidth">Width of the grip.</param>
        public virtual void DrawDayGripper(Graphics g, Rectangle rect, int gripWidth)
        {
            if (null == g) throw new ArgumentNullException("g");

            using (Brush m_Brush = new SolidBrush(Color.White))
            {
                g.FillRectangle(m_Brush, rect.Left, rect.Top - 1, gripWidth, rect.Height);
            }

            using (Pen m_Pen = new Pen(Color.Black))
            {
                g.DrawRectangle(m_Pen, rect.Left, rect.Top - 1, gripWidth, rect.Height);
            }
        }

        /// <summary>
        /// Draws the appointment.
        /// </summary>
        /// <param name="g">The g.</param>
        /// <param name="rect">The rect.</param>
        /// <param name="appointment">The appointment.</param>
        /// <param name="isSelected">if set to <c>true</c> [is selected].</param>
        /// <param name="gripWidth">Width of the grip.</param>
        public abstract void DrawAppointment(Graphics g, Rectangle rect, Appointment appointment, bool isSelected, int gripWidth);

        /// <summary>
        /// Draws all day background.
        /// </summary>
        /// <param name="g">The g.</param>
        /// <param name="rect">The rect.</param>
        public void DrawAllDayBackground(Graphics g, Rectangle rect)
        {
            if (null == g) throw new ArgumentNullException("g");

            using (Brush brush = new SolidBrush(InterpolateColors(this.BackColor, Color.Black, 0.5f)))
                g.FillRectangle(brush, rect);
        }

        /// <summary>
        /// Interpolates the colors.
        /// </summary>
        /// <param name="color1">The color1.</param>
        /// <param name="color2">The color2.</param>
        /// <param name="percentage">The percentage.</param>
        /// <returns></returns>
        public static Color InterpolateColors(Color color1, Color color2, float percentage)
        {
            int num1 = ((int)color1.R);
            int num2 = ((int)color1.G);
            int num3 = ((int)color1.B);
            int num4 = ((int)color2.R);
            int num5 = ((int)color2.G);
            int num6 = ((int)color2.B);
            byte num7 = Convert.ToByte(((float)(((float)num1) + (((float)(num4 - num1)) * percentage))));
            byte num8 = Convert.ToByte(((float)(((float)num2) + (((float)(num5 - num2)) * percentage))));
            byte num9 = Convert.ToByte(((float)(((float)num3) + (((float)(num6 - num3)) * percentage))));
            return Color.FromArgb(num7, num8, num9);
        }
    }
}
